package epoch.game.core.distr.call;

import java.io.IOException;

import org.apache.commons.lang3.builder.ToStringBuilder;

import epoch.game.core.distr.service.Service;
import epoch.game.core.serialize.ISerializable;
import epoch.game.core.serialize.IStreamReader;
import epoch.game.core.serialize.IStreamWriter;

/**
 * 远程调用信息，使用时注意保证Call的不可变性，只有在创建时候赋值，之后不管如何传递都不能修改其属性
 * @author will
 * @date 2016年4月1日 下午4:19:57
 */
public class Call implements ISerializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/** 请求ID */
	public long id;
	/** 服务id */
	public int serviceId;
	/** 请求处理线程标识，区分应该由那个服务线程处理 */
	public long callFlag;
	/** 调用函数名称 */
	public short methodKey;
	/** 调用函数参数 */
	public Object[] methodParam;				
	
	//--调用方信息
	/** 发送方NodeId */
	public int fromNodeId;
	/** 发送方portId(Call请求通过port发送，简化业务没精确到service) */
	public int fromPortId;
	/** 回调函数id */
	public long callbackId;
	/** 调用方信息，供调试用 */
	public String callerInfo;
	
	public boolean isActor = false; // caller 是否为actor
	
	public Service service;
	
	/**
	 * 创建CallReturn
	 * @return
	 */
	public CallReturn createCallReturn() {
		return new CallReturn(callbackId, fromNodeId, fromPortId, isActor);
	}
	
	public CallPoint createCallPoint(){
		return new CallPoint(fromNodeId, fromPortId, callbackId, isActor);
	}

	@Override
	public void writeTo(IStreamWriter stream) throws IOException {
		stream.writeInt(fromNodeId);
		stream.writeInt(fromPortId);
		stream.writeLong(id);
		stream.writeInt(serviceId);
		stream.writeShort(methodKey);
		stream.write(methodParam);
		stream.writeLong(callbackId);
		stream.writeLong(callFlag);
		stream.writeString(callerInfo);
		stream.writeBoolean(isActor);
	}
	
	@Override
	public void readFrom(IStreamReader stream) throws IOException {
		fromNodeId = stream.readInt();
		fromPortId = stream.readInt();
		id = stream.readLong();
		serviceId = stream.readInt();
		methodKey = stream.readShort();
		methodParam = stream.read();
		callbackId = stream.readLong();
		callFlag = stream.readLong();
		callerInfo = stream.readString();
		isActor = stream.readBoolean();
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this)
					.append("fromNodeId", fromNodeId)
					.append("fromPortId", fromPortId)
					.append("id", id)
					.append("serviceId", serviceId)
					.append("methodKey", methodKey)
					.append("methodParam", methodParam)
					.append("callbackId", callbackId)
					.append("callFlag", callFlag)
					.append("callerInfo", callerInfo)
					.append("isActor", isActor)
					.toString();
	}

}
